//
//  ZSNetworkTools.swift
//  3.Swift中网络的封装
//
//  Created by heima on 16/4/8.
//  Copyright © 2016年 heima. All rights reserved.
//

import UIKit
import AFNetworking

//swift 中的枚举
enum ZSHttpMethods: String {
    case POST = "POST"
    case GET = "GET"
}

//结构体中声明的成员变量需要用stati进行修饰
struct API {
    //线上的baseURL
    static let onlineHost = "https://api.weibo.com/"
    //测试的baseURL
    static let testHost = "https://dev.api.weibo.com"
    //获取授权的接口
    static let accessToken = "oauth2/access_token"
    //请求用户数据的接口
    static let user =  "2/users/show.json"
    //请求首页数据的接口
    static let homeData = "2/statuses/home_timeline.json"
    //发送微博文字的接口
    static let sendStatus = "2/statuses/update.json"
    //上传图片的接口
    static let uploadImage = "https://upload.api.weibo.com/2/statuses/upload.json"

    
}


class ZSNetworkTools: AFHTTPSessionManager {
    //声明单例对象
    static let sharedTools: ZSNetworkTools = {
        
        let tools = ZSNetworkTools(baseURL: NSURL(string: API.onlineHost))
        
        tools.responseSerializer.acceptableContentTypes?.insert("text/plain")
        
        return tools
    }()
    
    
    //封装所有的网络请求方法 所有的网络请求都是通过这个方法和 AFN进行联系

    func request(method: ZSHttpMethods,urlString: String, parameters: AnyObject?, finished: (result: AnyObject?, error: NSError?) -> ()) {
        
        //swift中就不能够使用利用协议 欺骗Xcode
        //为了达到封装的目的 可以将相同的闭包 抽取出来,当做参数传递给AFN框架
        let success =  { (task: NSURLSessionDataTask, result: AnyObject?) -> Void in
            //执行成功的回调
            finished(result: result, error: nil)
        }
        
        //定义失败的回调
        let failure = { (task: NSURLSessionDataTask?, error: NSError) -> Void in
            //执行失败的回调
            finished(result: nil, error: error)
        }
        
        if method == .GET {
            GET(urlString, parameters: parameters, progress: nil, success: success, failure: failure)
        } else {
            POST(urlString, parameters: parameters, progress: nil, success: success, failure: failure)
        }

    }

}

//扩展
extension ZSNetworkTools{
    
    func loadAccessToken(code:String,finished:(result:AnyObject?,error:NSError?)->()){
        
        let parameters = ["client_id":client_id,"client_secret":client_secret,"grant_type": "authorization_code","code":code,"redirect_uri":redirect_uri]
        
        request(.POST, urlString: API.accessToken, parameters: parameters, finished: finished)
    }
    
    
    //MARK: 加载用户的信息
    func loadUserInfo(token: AnyObject, uid: AnyObject,finished: (result: AnyObject?, error: NSError?) -> ()) {
        //字典数组中不能够添加nil
        let parameters = ["access_token": token, "uid": uid]
        request(.GET, urlString: API.user, parameters: parameters, finished: finished)
    }
    
   
    
    
    
    /*为什么要进行进一步的封装??为了更方便的管理api等,经过上面的步骤,把获取授权和获取用户数据的网络请求的代码放在了网络工具类中*/

    //添加一个方法获取home页的数据这个方法调用完毕会返回一个请求到的数据
    func loadHomeVCData(access_token:String,finished:(result: AnyObject?, error: NSError?) -> ()){
        
        request(.GET, urlString: API.homeData, parameters: ["access_token":access_token], finished: finished)
        
    }
    
    
    
    //网络工具类提供的加载更多数据的方法
    func loadMoreHomeVCData(max_id:Int64,access_token:String,finished:(result: AnyObject?, error: NSError?) -> ()){
        
        request(.GET, urlString: API.homeData, parameters: ["access_token":access_token,"max_id":"\(max_id)"], finished: finished)
        
    }
    
    
    //网络工具类提供的加载最新数据的方法
    func loadNewHomeVCData(since_id:Int64,access_token:String,finished:(result: AnyObject?, error: NSError?) -> ()){
        
        request(.GET, urlString: API.homeData, parameters: ["access_token":access_token,"since_id":"\(since_id)"], finished: finished)
        
    }

    
}

// MARK: - 上传图片的类扩展

extension ZSNetworkTools{

    //发送数据的方法
    func sendStatus(access_token:String,status:String,imageList:[UIImage] = [UIImage](),  finished: (result: AnyObject?, error: NSError?) -> ()){

        
        let parameters = ["access_token" : access_token,"status" : status]
        
        
        if imageList.count>0{
            //AFN
            POST(API.uploadImage, parameters: parameters, constructingBodyWithBlock: { (formdata) -> Void in
                //
                /**
                *将要上传的二进制数据添加到formdata
                *
                *  @param data  要上传的二进制数据
                *  @param name  服务器接收上传文件的字段名
                *  @param fileName  服务器获取到文件之后 以什么名称存储  名字可以随便取,新浪微博会按照自己的命名规则命名
                *  @param mimeType   文件类型
                *
                *  @return
                */
                // 第一个 '!' 表示一定获取一张图片  第二个 '!' 一定要将获取的图片转换 二进制
                let imageData = UIImagePNGRepresentation(imageList.first!)!
                formdata.appendPartWithFileData(imageData, name: "pic", fileName: "xxxxxx", mimeType: "image/jpeg")
                }, progress: nil, success: { (_, result) -> Void in
                    finished(result: result, error: nil)
                }, failure: { (_, error) -> Void in
                    finished(result: nil, error: error)
            })
        } else {
            //发布文本微博
            request(.POST, urlString: API.sendStatus, parameters: parameters, finished: finished)
        }
        
        
        


    }




}

